﻿using System.Collections;
using System.Collections.Generic;
using System.Text;
using Framework.Utilities;
using UnityEngine;
using UnityEngine.Networking;

namespace Framework.Core
{
    /// <summary>
    /// 网络管理，提供与服务器通信和资源下载功能。
    /// </summary>
    public class NetManager : MonoSingleton<NetManager>
    {
        /// <summary>
        /// POST成功回调。
        /// </summary>
        /// <param name="jsonStr">返回的Json字符串。</param>
        public delegate void OnPostSuccessCallback(string jsonStr);

        /// <summary>
        ///  POST失败回调。
        /// </summary>
        public delegate void OnPostFailCallback();

        /// <summary>
        /// GET成功回调。
        /// </summary>
        /// <param name="bytes">下载的字节流。</param>
        public delegate void OnGetSuccessCallback(byte[] bytes);

        /// <summary>
        /// GET失败回调。
        /// </summary>
        /// <param name="error">错误信息。.</param>
        public delegate void OnGetFailCallback(string error);

        /// <summary>
        /// 向指定地址服务器发送POST请求。
        /// </summary>
        /// <param name="url"> URL地址。</param>
        /// <param name="postData"> 可序列化数据对象。</param>
        /// <param name="sCall">成功回调。</param>
        /// <param name="fCall">失败回调。</param>
        public void Post(string url, System.Object postData, OnPostSuccessCallback sCall, OnPostFailCallback fCall)
        {
            StartCoroutine(DoPost(url, JsonUtility.ToJson(postData), sCall, fCall));
        }

        /// <summary>
        /// 向指定地址服务器发送POST请求。
        /// </summary>
        /// <param name="url">The URL.</param>
        /// <param name="postDataStr">The post data string.</param>
        /// <param name="sCall">The s call.</param>
        /// <param name="fCall">The f call.</param>
        /// <returns></returns>
        private IEnumerator DoPost(string url, string postDataStr, OnPostSuccessCallback sCall, OnPostFailCallback fCall)
        {
            if (Application.internetReachability != NetworkReachability.NotReachable)
            {
                Debug.Log("Connent:" + url);

                var request = new UnityWebRequest(url, "POST");

                Debug.Log("post to json" + postDataStr);
                byte[] postBytes = Encoding.Default.GetBytes(postDataStr);

                request.uploadHandler = (UploadHandler)new UploadHandlerRaw(postBytes);
                request.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer();

                request.SetRequestHeader("Content-Type", "application/json");
                request.SetRequestHeader("Accept-Language", "zh-CN,en;q=0.8");

                yield return request.Send();

                Debug.Log(" Load url：" + url + request.downloadHandler.text);
                Debug.Log(" Status Code: " + request.responseCode);

                if (request.responseCode == 200)
                {
                    string text = request.downloadHandler.text;

                    Debug.Log("Result : " + text);
                    if (sCall != null)
                    {
                        sCall(text);
                    }
                }
                else
                {
                    //读取错误
                    string text = request.downloadHandler.text;
                    Debug.Log("Result : " + text);
                    if (fCall != null)
                    {
                        fCall();
                    }
                }
            }
            else
            {
                Debug.Log("Netork NotReachable.");
                if (fCall != null)
                {
                    fCall();
                }
            }
        }

        /// <summary>
        /// 向指定地址服务器发送GET请求。
        /// </summary>
        /// <param name="url">URL地址。</param>
        /// <param name="sCall">成功回调。</param>
        /// <param name="fCall">失败回调。</param>
        public void Get(string url, OnGetSuccessCallback sCall, OnGetFailCallback fCall)
        {
            StartCoroutine(DoGet(url, sCall, fCall));
        }

        /// <summary>
        /// 向指定地址服务器发送GET请求。
        /// </summary>
        /// <param name="url">URL地址。/param>
        /// <param name="sCall">成功回调。</param>
        /// <param name="fCall">失败回调。</param>
        /// <returns>迭代器。</returns>
        private IEnumerator DoGet(string url, OnGetSuccessCallback sCall, OnGetFailCallback fCall)
        {
            //建立WWW连接
            WWW www = new WWW(url);
            yield return www;

            //如果没有发生错误
            if (string.IsNullOrEmpty(www.error))
            {
                if (sCall != null)
                {
                    sCall(www.bytes);
                }
            }
            else
            {
                if (fCall != null)
                {
                    fCall(www.error);
                }
            }
            //释放www资源
            www.Dispose();
        }
    }
}